import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Vector;

public class BowFeatureVector {
  public static class WordCount implements Comparable<WordCount> {
    String word_;
    int count_;

    public WordCount(String word, int count) {
      word_ = word;
      count_ = count;
    }

    public String getWord() {
      return word_;
    }

    public int getCount() {
      return count_;
    }

    public int compareTo(WordCount wc) {
      return wc.getCount() - getCount();
    }
  }
  
  Vector<WordCount> featureV_ = null;
  int featLength_;
  int cumFreq_;
  
  public BowFeatureVector(HashMap<String, Integer> hm, int len) {
    featureV_ = new Vector<BowFeatureVector.WordCount>();
    cumFreq_ = 0;
    featLength_ = len;

    Iterator<Map.Entry<String, Integer>> it = hm.entrySet().iterator();
    
    while(it.hasNext()) {
      Map.Entry<String, Integer> mp = it.next();
      featureV_.add(new WordCount(mp.getKey(), mp.getValue()));
      cumFreq_ += mp.getValue();
    }
    
    Collections.sort(featureV_);
    
    int IGNORE_TOO_FREQUENT = 0;    
    while (featureV_.size() > featLength_ && IGNORE_TOO_FREQUENT > 0) {
      IGNORE_TOO_FREQUENT--;
      WordCount wc = featureV_.remove(0);
      cumFreq_ -= wc.getCount();
    }
    
    while (featureV_.size() > featLength_) {
      WordCount wc = featureV_.remove(featureV_.size() - 1);
      cumFreq_ -= wc.getCount();
    }
  }
  
  public int getFeatureLength() {
    return featLength_;
  }
  
  public double getFeatureCount(String word) {
    double res = 0.0;

    for (int i = 0 ; i < featureV_.size(); ++i) {
      WordCount wc = featureV_.get(i);
      
      if (wc.getWord().equals(word)) {
        res = wc.getCount();
        break;
      }
    }
    
    return res;
  }
  
  public double getFeatureWeight(int index) {
    WordCount wc = featureV_.get(index);
    return (double)(wc.getCount()) / cumFreq_;
  }
  
  public Vector<String> getFeatureVector() {
    Vector<String> v = new Vector<String>();
    for (int i = 0; i < featureV_.size(); ++i) {
      v.add(featureV_.get(i).getWord());
    }
    return v;
  }
}
